package net.cyue.web.easyquery.core.http.adapter;

import net.cyue.web.easyquery.core.http.HTTPRequestMethod;
import net.cyue.web.easyquery.core.http.api.IHTTPRouter;
import net.cyue.web.easyquery.core.http.api.IHTTPServer;
import net.cyue.web.easyquery.core.http.handler.api.IWebRequestHandler;
import net.cyue.web.easyquery.core.service.api.IService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * HTTP 服务适配器抽象类
 */
public abstract class AbstractHTTPServer<TServer> implements IHTTPServer, IService<TServer> {

    public static final HTTPRequestMethod[] ALL_REQUEST_METHODS = new HTTPRequestMethod[]{
        HTTPRequestMethod.GET,
        HTTPRequestMethod.POST,
        HTTPRequestMethod.DELETE,
        HTTPRequestMethod.PUT,
        HTTPRequestMethod.PATCH,
    };
    private final Logger logger = LoggerFactory.getLogger(this.toString());

    protected TServer server;
    /**
     * 路由器
     */
    protected IHTTPRouter router;

    public AbstractHTTPServer() {}

    /**
     * 构造函数
     * @param server 原始服务示例
     */
    public AbstractHTTPServer(TServer server) {
        this.server = server;
    }

    /**
     * 构造函数
     * @param router 路由器实现实例
     */
    public AbstractHTTPServer(IHTTPRouter router) {
        this.router = router;
    }

    /**
     * 构造函数
     * @param server 原始服务示例
     * @param router 路由器实例
     */
    public AbstractHTTPServer(TServer server, IHTTPRouter router) {
        this.server = server;
        this.router = router;
    }

    /**
     * 获取原始服务示例
     * @return 原始服务示例
     */
    @Override
    public TServer getPrototype() {
        return this.server;
    }

    /**
     * 获取原始服务示例
     * @return 原始服务示例
     */
    public TServer getServer() {
        return this.server;
    }

    /**
     * 设置路由器
     * @param router 路由器实例
     */
    public void setRouter(IHTTPRouter router) {
        this.router = router;
    }

    /**
     * 添加路由
     * @param path api 路径
     * @param handler 请求处理器实例
     * @param methods 接受的请求方法
     * @return 添加结果
     */
    protected boolean addRoute(String path, IWebRequestHandler handler, HTTPRequestMethod[] methods) {
        if (this.router == null) {
            this.logger.warn("Router is not set");
            return false;
        }
        return this.router.addRoute(path, handler, methods);
    }

    @Override
    public boolean get(IWebRequestHandler handler) {
        return this.addRoute("/", handler, new HTTPRequestMethod[]{HTTPRequestMethod.GET});
    }

    @Override
    public boolean get(String path, IWebRequestHandler handler) {
        return this.addRoute(path, handler, new HTTPRequestMethod[]{HTTPRequestMethod.GET});
    }

    @Override
    public boolean post(IWebRequestHandler handler) {
        return this.addRoute("/", handler, new HTTPRequestMethod[]{HTTPRequestMethod.POST});
    }

    @Override
    public boolean post(String path, IWebRequestHandler handler) {
        return this.addRoute(path, handler, new HTTPRequestMethod[]{HTTPRequestMethod.POST});
    }

    @Override
    public boolean head(IWebRequestHandler handler) {
        return this.addRoute("/", handler, new HTTPRequestMethod[]{HTTPRequestMethod.HEAD});
    }

    @Override
    public boolean head(String path, IWebRequestHandler handler) {
        return this.addRoute(path, handler, new HTTPRequestMethod[]{HTTPRequestMethod.HEAD});
    }

    @Override
    public boolean delete(IWebRequestHandler handler) {
        return this.addRoute("/", handler, new HTTPRequestMethod[]{HTTPRequestMethod.DELETE});
    }

    @Override
    public boolean delete(String path, IWebRequestHandler handler) {
        return this.addRoute(path, handler, new HTTPRequestMethod[]{HTTPRequestMethod.DELETE});
    }

    @Override
    public boolean put(IWebRequestHandler handler) {
        return this.addRoute("/", handler, new HTTPRequestMethod[]{HTTPRequestMethod.PUT});
    }

    @Override
    public boolean put(String path, IWebRequestHandler handler) {
        return this.addRoute(path, handler, new HTTPRequestMethod[]{HTTPRequestMethod.PUT});
    }

    @Override
    public boolean patch(IWebRequestHandler handler) {
        return this.addRoute("/", handler, new HTTPRequestMethod[]{HTTPRequestMethod.PATCH});
    }

    @Override
    public boolean patch(String path, IWebRequestHandler handler) {
        return this.addRoute(path, handler, new HTTPRequestMethod[]{HTTPRequestMethod.PATCH});
    }

    @Override
    public boolean options(IWebRequestHandler handler) {
        return this.addRoute("/", handler, new HTTPRequestMethod[]{HTTPRequestMethod.OPTIONS});
    }

    @Override
    public boolean options(String path, IWebRequestHandler handler) {
        return this.addRoute(path, handler, new HTTPRequestMethod[]{HTTPRequestMethod.OPTIONS});
    }

    @Override
    public boolean all(IWebRequestHandler handler) {
        return this.addRoute(
            "/",
            handler,
            ALL_REQUEST_METHODS
        );
    }

    @Override
    public boolean all(String path, IWebRequestHandler handler) {
        return this.addRoute(
            path,
            handler,
            ALL_REQUEST_METHODS
        );
    }
}
